package com.yzcity.cinema.web.rest;

import com.yzcity.cinema.RedisTestContainerExtension;
import com.yzcity.cinema.YzcitycinemaApp;
import com.yzcity.cinema.domain.BaseType;
import com.yzcity.cinema.repository.BaseTypeRepository;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

/**
 * Integration tests for the {@link BaseTypeResource} REST controller.
 */
@SpringBootTest(classes = YzcitycinemaApp.class)
@ExtendWith({ RedisTestContainerExtension.class, MockitoExtension.class })
@AutoConfigureMockMvc
@WithMockUser
public class BaseTypeResourceIT {

    private static final String DEFAULT_NAME = "AAAAAAAAAA";
    private static final String UPDATED_NAME = "BBBBBBBBBB";

    private static final String DEFAULT_KEY = "AAAAAAAAAA";
    private static final String UPDATED_KEY = "BBBBBBBBBB";

    private static final String DEFAULT_DESCRIPTION = "AAAAAAAAAA";
    private static final String UPDATED_DESCRIPTION = "BBBBBBBBBB";

    private static final Boolean DEFAULT_SYSTEM_BUILTIN = false;
    private static final Boolean UPDATED_SYSTEM_BUILTIN = true;

    private static final Long DEFAULT_COMPANY_ID = 1L;
    private static final Long UPDATED_COMPANY_ID = 2L;

    private static final String DEFAULT_CREATED_BY = "AAAAAAAAAA";
    private static final String UPDATED_CREATED_BY = "BBBBBBBBBB";

    private static final Instant DEFAULT_CREATED_TIME = Instant.ofEpochMilli(0L);
    private static final Instant UPDATED_CREATED_TIME = Instant.now().truncatedTo(ChronoUnit.MILLIS);

    private static final String DEFAULT_LAST_MODIFIED_BY = "AAAAAAAAAA";
    private static final String UPDATED_LAST_MODIFIED_BY = "BBBBBBBBBB";

    private static final Instant DEFAULT_LAST_MODIFIED_TIME = Instant.ofEpochMilli(0L);
    private static final Instant UPDATED_LAST_MODIFIED_TIME = Instant.now().truncatedTo(ChronoUnit.MILLIS);

    @Autowired
    private BaseTypeRepository baseTypeRepository;

    @Autowired
    private EntityManager em;

    @Autowired
    private MockMvc restBaseTypeMockMvc;

    private BaseType baseType;

    /**
     * Create an entity for this test.
     *
     * This is a static method, as tests for other entities might also need it,
     * if they test an entity which requires the current entity.
     */
    public static BaseType createEntity(EntityManager em) {
        BaseType baseType = new BaseType()
            .name(DEFAULT_NAME)
            .key(DEFAULT_KEY)
            .description(DEFAULT_DESCRIPTION)
            .systemBuiltin(DEFAULT_SYSTEM_BUILTIN)
            .companyId(DEFAULT_COMPANY_ID)
            .createdBy(DEFAULT_CREATED_BY)
            .createdTime(DEFAULT_CREATED_TIME)
            .lastModifiedBy(DEFAULT_LAST_MODIFIED_BY)
            .lastModifiedTime(DEFAULT_LAST_MODIFIED_TIME);
        return baseType;
    }
    /**
     * Create an updated entity for this test.
     *
     * This is a static method, as tests for other entities might also need it,
     * if they test an entity which requires the current entity.
     */
    public static BaseType createUpdatedEntity(EntityManager em) {
        BaseType baseType = new BaseType()
            .name(UPDATED_NAME)
            .key(UPDATED_KEY)
            .description(UPDATED_DESCRIPTION)
            .systemBuiltin(UPDATED_SYSTEM_BUILTIN)
            .companyId(UPDATED_COMPANY_ID)
            .createdBy(UPDATED_CREATED_BY)
            .createdTime(UPDATED_CREATED_TIME)
            .lastModifiedBy(UPDATED_LAST_MODIFIED_BY)
            .lastModifiedTime(UPDATED_LAST_MODIFIED_TIME);
        return baseType;
    }

    @BeforeEach
    public void initTest() {
        baseType = createEntity(em);
    }

    @Test
    @Transactional
    public void createBaseType() throws Exception {
        int databaseSizeBeforeCreate = baseTypeRepository.findAll().size();
        // Create the BaseType
        restBaseTypeMockMvc.perform(post("/api/base-types")
            .contentType(MediaType.APPLICATION_JSON)
            .content(TestUtil.convertObjectToJsonBytes(baseType)))
            .andExpect(status().isCreated());

        // Validate the BaseType in the database
        List<BaseType> baseTypeList = baseTypeRepository.findAll();
        assertThat(baseTypeList).hasSize(databaseSizeBeforeCreate + 1);
        BaseType testBaseType = baseTypeList.get(baseTypeList.size() - 1);
        assertThat(testBaseType.getName()).isEqualTo(DEFAULT_NAME);
        assertThat(testBaseType.getKey()).isEqualTo(DEFAULT_KEY);
        assertThat(testBaseType.getDescription()).isEqualTo(DEFAULT_DESCRIPTION);
        assertThat(testBaseType.isSystemBuiltin()).isEqualTo(DEFAULT_SYSTEM_BUILTIN);
        assertThat(testBaseType.getCompanyId()).isEqualTo(DEFAULT_COMPANY_ID);
        assertThat(testBaseType.getCreatedBy()).isEqualTo(DEFAULT_CREATED_BY);
        assertThat(testBaseType.getCreatedTime()).isEqualTo(DEFAULT_CREATED_TIME);
        assertThat(testBaseType.getLastModifiedBy()).isEqualTo(DEFAULT_LAST_MODIFIED_BY);
        assertThat(testBaseType.getLastModifiedTime()).isEqualTo(DEFAULT_LAST_MODIFIED_TIME);
    }

    @Test
    @Transactional
    public void createBaseTypeWithExistingId() throws Exception {
        int databaseSizeBeforeCreate = baseTypeRepository.findAll().size();

        // Create the BaseType with an existing ID
        baseType.setId(1L);

        // An entity with an existing ID cannot be created, so this API call must fail
        restBaseTypeMockMvc.perform(post("/api/base-types")
            .contentType(MediaType.APPLICATION_JSON)
            .content(TestUtil.convertObjectToJsonBytes(baseType)))
            .andExpect(status().isBadRequest());

        // Validate the BaseType in the database
        List<BaseType> baseTypeList = baseTypeRepository.findAll();
        assertThat(baseTypeList).hasSize(databaseSizeBeforeCreate);
    }


    @Test
    @Transactional
    public void checkNameIsRequired() throws Exception {
        int databaseSizeBeforeTest = baseTypeRepository.findAll().size();
        // set the field null
        baseType.setName(null);

        // Create the BaseType, which fails.


        restBaseTypeMockMvc.perform(post("/api/base-types")
            .contentType(MediaType.APPLICATION_JSON)
            .content(TestUtil.convertObjectToJsonBytes(baseType)))
            .andExpect(status().isBadRequest());

        List<BaseType> baseTypeList = baseTypeRepository.findAll();
        assertThat(baseTypeList).hasSize(databaseSizeBeforeTest);
    }

    @Test
    @Transactional
    public void checkKeyIsRequired() throws Exception {
        int databaseSizeBeforeTest = baseTypeRepository.findAll().size();
        // set the field null
        baseType.setKey(null);

        // Create the BaseType, which fails.


        restBaseTypeMockMvc.perform(post("/api/base-types")
            .contentType(MediaType.APPLICATION_JSON)
            .content(TestUtil.convertObjectToJsonBytes(baseType)))
            .andExpect(status().isBadRequest());

        List<BaseType> baseTypeList = baseTypeRepository.findAll();
        assertThat(baseTypeList).hasSize(databaseSizeBeforeTest);
    }

    @Test
    @Transactional
    public void checkSystemBuiltinIsRequired() throws Exception {
        int databaseSizeBeforeTest = baseTypeRepository.findAll().size();
        // set the field null
        baseType.setSystemBuiltin(null);

        // Create the BaseType, which fails.


        restBaseTypeMockMvc.perform(post("/api/base-types")
            .contentType(MediaType.APPLICATION_JSON)
            .content(TestUtil.convertObjectToJsonBytes(baseType)))
            .andExpect(status().isBadRequest());

        List<BaseType> baseTypeList = baseTypeRepository.findAll();
        assertThat(baseTypeList).hasSize(databaseSizeBeforeTest);
    }

    @Test
    @Transactional
    public void getAllBaseTypes() throws Exception {
        // Initialize the database
        baseTypeRepository.saveAndFlush(baseType);

        // Get all the baseTypeList
        restBaseTypeMockMvc.perform(get("/api/base-types?sort=id,desc"))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
            .andExpect(jsonPath("$.[*].id").value(hasItem(baseType.getId().intValue())))
            .andExpect(jsonPath("$.[*].name").value(hasItem(DEFAULT_NAME)))
            .andExpect(jsonPath("$.[*].key").value(hasItem(DEFAULT_KEY)))
            .andExpect(jsonPath("$.[*].description").value(hasItem(DEFAULT_DESCRIPTION)))
            .andExpect(jsonPath("$.[*].systemBuiltin").value(hasItem(DEFAULT_SYSTEM_BUILTIN.booleanValue())))
            .andExpect(jsonPath("$.[*].companyId").value(hasItem(DEFAULT_COMPANY_ID.intValue())))
            .andExpect(jsonPath("$.[*].createdBy").value(hasItem(DEFAULT_CREATED_BY)))
            .andExpect(jsonPath("$.[*].createdTime").value(hasItem(DEFAULT_CREATED_TIME.toString())))
            .andExpect(jsonPath("$.[*].lastModifiedBy").value(hasItem(DEFAULT_LAST_MODIFIED_BY)))
            .andExpect(jsonPath("$.[*].lastModifiedTime").value(hasItem(DEFAULT_LAST_MODIFIED_TIME.toString())));
    }
    
    @Test
    @Transactional
    public void getBaseType() throws Exception {
        // Initialize the database
        baseTypeRepository.saveAndFlush(baseType);

        // Get the baseType
        restBaseTypeMockMvc.perform(get("/api/base-types/{id}", baseType.getId()))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
            .andExpect(jsonPath("$.id").value(baseType.getId().intValue()))
            .andExpect(jsonPath("$.name").value(DEFAULT_NAME))
            .andExpect(jsonPath("$.key").value(DEFAULT_KEY))
            .andExpect(jsonPath("$.description").value(DEFAULT_DESCRIPTION))
            .andExpect(jsonPath("$.systemBuiltin").value(DEFAULT_SYSTEM_BUILTIN.booleanValue()))
            .andExpect(jsonPath("$.companyId").value(DEFAULT_COMPANY_ID.intValue()))
            .andExpect(jsonPath("$.createdBy").value(DEFAULT_CREATED_BY))
            .andExpect(jsonPath("$.createdTime").value(DEFAULT_CREATED_TIME.toString()))
            .andExpect(jsonPath("$.lastModifiedBy").value(DEFAULT_LAST_MODIFIED_BY))
            .andExpect(jsonPath("$.lastModifiedTime").value(DEFAULT_LAST_MODIFIED_TIME.toString()));
    }
    @Test
    @Transactional
    public void getNonExistingBaseType() throws Exception {
        // Get the baseType
        restBaseTypeMockMvc.perform(get("/api/base-types/{id}", Long.MAX_VALUE))
            .andExpect(status().isNotFound());
    }

    @Test
    @Transactional
    public void updateBaseType() throws Exception {
        // Initialize the database
        baseTypeRepository.saveAndFlush(baseType);

        int databaseSizeBeforeUpdate = baseTypeRepository.findAll().size();

        // Update the baseType
        BaseType updatedBaseType = baseTypeRepository.findById(baseType.getId()).get();
        // Disconnect from session so that the updates on updatedBaseType are not directly saved in db
        em.detach(updatedBaseType);
        updatedBaseType
            .name(UPDATED_NAME)
            .key(UPDATED_KEY)
            .description(UPDATED_DESCRIPTION)
            .systemBuiltin(UPDATED_SYSTEM_BUILTIN)
            .companyId(UPDATED_COMPANY_ID)
            .createdBy(UPDATED_CREATED_BY)
            .createdTime(UPDATED_CREATED_TIME)
            .lastModifiedBy(UPDATED_LAST_MODIFIED_BY)
            .lastModifiedTime(UPDATED_LAST_MODIFIED_TIME);

        restBaseTypeMockMvc.perform(put("/api/base-types")
            .contentType(MediaType.APPLICATION_JSON)
            .content(TestUtil.convertObjectToJsonBytes(updatedBaseType)))
            .andExpect(status().isOk());

        // Validate the BaseType in the database
        List<BaseType> baseTypeList = baseTypeRepository.findAll();
        assertThat(baseTypeList).hasSize(databaseSizeBeforeUpdate);
        BaseType testBaseType = baseTypeList.get(baseTypeList.size() - 1);
        assertThat(testBaseType.getName()).isEqualTo(UPDATED_NAME);
        assertThat(testBaseType.getKey()).isEqualTo(UPDATED_KEY);
        assertThat(testBaseType.getDescription()).isEqualTo(UPDATED_DESCRIPTION);
        assertThat(testBaseType.isSystemBuiltin()).isEqualTo(UPDATED_SYSTEM_BUILTIN);
        assertThat(testBaseType.getCompanyId()).isEqualTo(UPDATED_COMPANY_ID);
        assertThat(testBaseType.getCreatedBy()).isEqualTo(UPDATED_CREATED_BY);
        assertThat(testBaseType.getCreatedTime()).isEqualTo(UPDATED_CREATED_TIME);
        assertThat(testBaseType.getLastModifiedBy()).isEqualTo(UPDATED_LAST_MODIFIED_BY);
        assertThat(testBaseType.getLastModifiedTime()).isEqualTo(UPDATED_LAST_MODIFIED_TIME);
    }

    @Test
    @Transactional
    public void updateNonExistingBaseType() throws Exception {
        int databaseSizeBeforeUpdate = baseTypeRepository.findAll().size();

        // If the entity doesn't have an ID, it will throw BadRequestAlertException
        restBaseTypeMockMvc.perform(put("/api/base-types")
            .contentType(MediaType.APPLICATION_JSON)
            .content(TestUtil.convertObjectToJsonBytes(baseType)))
            .andExpect(status().isBadRequest());

        // Validate the BaseType in the database
        List<BaseType> baseTypeList = baseTypeRepository.findAll();
        assertThat(baseTypeList).hasSize(databaseSizeBeforeUpdate);
    }

    @Test
    @Transactional
    public void deleteBaseType() throws Exception {
        // Initialize the database
        baseTypeRepository.saveAndFlush(baseType);

        int databaseSizeBeforeDelete = baseTypeRepository.findAll().size();

        // Delete the baseType
        restBaseTypeMockMvc.perform(delete("/api/base-types/{id}", baseType.getId())
            .accept(MediaType.APPLICATION_JSON))
            .andExpect(status().isNoContent());

        // Validate the database contains one less item
        List<BaseType> baseTypeList = baseTypeRepository.findAll();
        assertThat(baseTypeList).hasSize(databaseSizeBeforeDelete - 1);
    }
}
